package syspizza.DAO;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import syspizza.cliente.Cliente;
import syspizza.exceptions.CampoInvalidoException;


public class ClienteDAO implements IClienteDAO<Cliente> {
    
    private final String PASTA = "\\SysPizza\\dados\\clientes\\";
    private final String ARQUIVO = "clientes.dat";

    @Override
    public boolean insert(Cliente cliente) throws CampoInvalidoException {
        List<Cliente> clientes = getAll();
        int codigo = getNextCodigo();

        cliente.setCodigo(codigo);
        clientes.add(cliente);
        if (validaCampos(cliente)) {
            write(clientes);
        } else {
            throw new CampoInvalidoException("Campo inválido");
        }
        return true;
    }

    private boolean validaCampos(Cliente cliente) {

        if (cliente.getNome().isEmpty()) {
            return false;
        }
        if (cliente.getEndereco().isEmpty()) {
            return false;
        }
        if (cliente.getTelefone().isEmpty()) {
            return false;
        }
        if (cliente.getCelular().isEmpty()) {
            return false;
        }
        if (cliente.getCEP().isEmpty()) {
            return false;
        }
        return true;
    }

    @Override
    public Cliente get(int codigo) {
        for (Cliente cliente : getAll()) {
            if (cliente.getCodigo() == codigo) {
                return cliente;
            }
        }
        return null;
    }

    @Override
    public void delete(int codigo) {
        List<Cliente> clientes = getAll();
        clientes.removeIf(p -> p.getCodigo() == codigo);//caraca! Tem predicado no java 8
        write(clientes);
    }

    public List<Cliente> getAll(String nome) {
        List<Cliente> clientes = getAll();
        if (!(nome.isEmpty() || nome == null)) {
            clientes.removeIf(p -> !p.getNome().toUpperCase().contains(nome.toUpperCase()));
        }
        return clientes;
    }

    private void write(List<Cliente> clientes) {
        //implementar verificador de codigo duplicado.
        File arq = new File(PASTA);
        //cria pasta se nao existir
        if (!arq.exists()) {
            arq.mkdirs();
        }
        try {
            File arq1 = new File(PASTA + ARQUIVO);
            FileOutputStream fos = new FileOutputStream(arq1);
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(clientes);
            oos.close();
            fos.close();

        } catch (FileNotFoundException ex) {
            Logger.getLogger(ClienteDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(ClienteDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public List<Cliente> getAll() {
        List<Cliente> clientes = new ArrayList<>();

        //vai varrer os registros e gerar o proximo codigo disponivel
        File arq = new File(PASTA);
        if (!arq.exists()) {
            arq.mkdirs();
            return clientes;// se nao existir pasta retorna lista vazia
        }
        //vai varrer os registros
        File[] arquivos = arq.listFiles();
        for (File file : arquivos) {
            if (file.isFile()) {
                FileInputStream fis = null;
                ObjectInputStream ois = null;
                try {
                    fis = new FileInputStream(file);
                    ois = new ObjectInputStream(fis);

                    clientes = (ArrayList) ois.readObject();

                    fis.close();
                    ois.close();

                } catch (Exception ex) {
                    System.err.println("Erro: " + ex.getMessage() + " - " + ex.getStackTrace());
                    Logger.getLogger(ClienteDAO.class.getName()).log(Level.SEVERE, null, ex);
                }

            }
        }//fim for
        return clientes;
    }

    @Override
    public List<Cliente> getByName(String nome) {
        List<Cliente> clientes = getAll();
        if (nome.isEmpty() || nome.equals(null)) {
            return clientes;
        }
        if (clientes != null) {
            clientes.removeIf(c -> !c.getNome().toUpperCase().contains(nome.toUpperCase()));
        }
        return clientes;
    }

    @Override
    public int getNextCodigo() {
        int codigo = 0;
        //vai varrer os registros e gerar o proximo codigo disponivel
        List<Cliente> clientes = getAll();
        for (Cliente cliente : clientes) {
            if (cliente.getCodigo() > codigo) {
                codigo = cliente.getCodigo();
            }
        }
        codigo++;
        return codigo;
    }

    @Override
    public void update(Cliente cliente) throws CampoInvalidoException {
        if (!validaCampos(cliente)) {
            throw new CampoInvalidoException("Campo inválido!");
        }

        List<Cliente> clientes = getAll();
        List<Cliente> auxiliar = getAll();

        for (int i = 0; i < clientes.size(); i++) {
            if (clientes.get(i).getCodigo() == cliente.getCodigo()) {
                auxiliar.remove(i);
                auxiliar.add(cliente);
            }
        }
        write(auxiliar);
    }

}
